﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GPSTool : SingletonMono<GPSTool> {

    private const int EARTH_RADIUS = 6378137;

    AndroidUtil util;
    Action<float, float, double> callback;

    public AndroidUtil Util
    {
        get
        {
            if(util==null)
            {
                util = new AndroidUtil(gameObject, "_CallBack");
            }
            return util;
        }
    }
    public void GetLocation(Action<float, float,double> _callback)
    {
        //#if UNITY_EDITOR
        //        //callback(35.69839f, 114.7943f, 0);
        //        callback(34.80376f,113.5955f, 0);
        //#else
        //        StartCoroutine(CoStartGPS(_callback));

        if (!Input.location.isEnabledByUser)
        {
            Debug.Log("请启用GPS定位");
            return;
        }


        Util.StartLocation();
        callback = _callback;
//#endif
    }

    void _CallBack(string locationResult)
    {
        if(locationResult == "定位失败")
        {
            Debug.Log("定位失败");
        }
        else
        {
            string[] locs = locationResult.Split(',');
            callback(float.Parse(locs[0]),float.Parse(locs[1]), double.Parse(locs[2]));
        }
    }

    IEnumerator CoStartGPS(Action<float,float, double> callback)
    {
        // Input.location 用于访问设备的位置属性（手持设备）, 静态的LocationService位置
        // LocationService.isEnabledByUser 用户设置里的定位服务是否启用
        if (!Input.location.isEnabledByUser)
        {
            Debug.Log("请启用GPS定位");
            yield break;
        }
        // LocationService.Start() 启动位置服务的更新,最后一个位置坐标会被使用
        Input.location.Start(0.1f,0.1f);
        int maxWait = 20;
        while (Input.location.status == LocationServiceStatus.Initializing && maxWait > 0)
        {
            // 暂停协同程序的执行(1秒)
            yield return new WaitForSeconds(1);
            maxWait--;
        }
        if (maxWait < 1)
        {
            Debug.Log("GPS服务超时");
            yield break;
        }
        if (Input.location.status == LocationServiceStatus.Failed)
        {
            Debug.Log("无法确定设备位置");
            yield break;
        }
        else
        {
            callback(Input.location.lastData.latitude, Input.location.lastData.longitude, Input.location.lastData.timestamp);
        }
    }

    public void Stop()
    {
        Input.location.Stop();
    }


    /// <summary>
    /// 根据两个经纬度，得到Unity中p2相对于p1的向量
    /// </summary>
    /// <param name="lat1">p1.N</param>
    /// <param name="lng1">p1.E</param>
    /// <param name="lat2">p2.N</param>
    /// <param name="lng2">p2.E</param>
    public static Vector3 GetUnityVector3(Location loc1, Location loc2)
    {
        //var v1 = GetCoordinate(loc1.latitude, loc1.longitude);
        //var v2 = GetCoordinate(loc2.latitude, loc2.longitude);
        //var v3 = v2 - v1;
        //v3 = Quaternion.FromToRotation(v1.normalized ,new Vector3(0, 1, 0)) * v3;
        //return v3;
        var v3 = loc1-loc2;
        //return new Vector3(v3.longitude, 0, v3.latitude)*100000;
        //return new Vector3(v3.longitude, 0, v3.latitude)*55000;
        return new Vector3(v3.longitude, 0, v3.latitude)*10000;
    }

    /// <summary>
    /// 经纬度坐标转换为空间直角坐标
    /// </summary>
    /// <param name="R"></param>
    /// <param name="lat"></param>
    /// <param name="lng"></param>
    public static Vector3 GetCoordinate(float lat, float lng)
    {
        lat = ToRad(lat);
        lng = ToRad(lng);
        Vector3 result;
        result.x = EARTH_RADIUS * Mathf.Cos(lat) * Mathf.Cos(lng);
        result.y = EARTH_RADIUS * Mathf.Cos(lat) * Mathf.Sin(lng);
        result.z = EARTH_RADIUS * Mathf.Sin(lat);
        return result;
    }

    /// <summary>
    /// 计算两点位置的距离，返回两点的距离，单位 米
    /// 该公式为GOOGLE提供，误差小于0.2米
    /// </summary>
    /// <param name="lat1">第一点纬度</param>
    /// <param name="lng1">第一点经度</param>
    /// <param name="lat2">第二点纬度</param>
    /// <param name="lng2">第二点经度</param>
    public static double GetDistance(float lat1, float lng1, float lat2, float lng2)
    {
        double radLat1 = ToRad(lat1);
        double radLng1 = ToRad(lng1);
        double radLat2 = ToRad(lat2);
        double radLng2 = ToRad(lng2);
        double a = radLat1 - radLat2;
        double b = radLng1 - radLng2;
        double result = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) + Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin(b / 2), 2))) * EARTH_RADIUS;
        return result;
    }
    /// <summary>
    /// 角度转弧度
    /// </summary>
    /// <param name="angle">角度</param>
    private static float ToRad(float angle)
    {
        return angle * (float)Math.PI / 180;
    }
}
